package cn.yj.quartz.job;

import cn.yj.quartz.QuartzJob;
import cn.yj.quartz.common.ScheduleConst;
import cn.yj.quartz.service.ScheduleExecute;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;
import java.util.Objects;

/**
 * 主要处理个日志问题
 * @author 永健
 * @since 2022-01-14 14:07
 */
public abstract class AbstractQuartzJob extends QuartzJobBean {

    private static final Logger logger= LoggerFactory.getLogger(ScheduleExecute.class);

    private static final ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        Object o = jobDetail.getJobDataMap().get(ScheduleConst.TASK_PROPERTIES);
        if (Objects.isNull(o)){
            return;
        }
        QuartzJob quartzJob = new QuartzJob();
        BeanUtils.copyProperties(o,quartzJob);
        before(jobExecutionContext,quartzJob);
        try {
            doExecute(jobExecutionContext,quartzJob);
        } catch (Exception e) {
            error(e,jobExecutionContext,quartzJob);
        }finally {
            after(jobExecutionContext,quartzJob);
        }
    }

    protected abstract void doExecute(JobExecutionContext jobExecutionContext, QuartzJob quartzJob) throws Exception;

    private void before(JobExecutionContext jobExecutionContext, QuartzJob quartzJob){
        threadLocal.set(new Date());
    }

    private void after(JobExecutionContext jobExecutionContext, QuartzJob quartzJob){
        Date date = threadLocal.get();
        threadLocal.remove();
        long currentTimeMillis = System.currentTimeMillis();
        logger.info("任务 {} 执行花费 {} /ms",quartzJob.getJobName(),currentTimeMillis-date.getTime());
    }

    private void error(Exception e,JobExecutionContext jobExecutionContext, QuartzJob quartzJob){
        e.printStackTrace();
    }
}
